/*
    File:       OS.h

    Contains:   OS utility functions. Memory allocation, time, etc.



*/

#ifndef _OS_H_
#define _OS_H_

#ifdef  __linux__
#include <sys/errno.h>
#else
#include <errno.h>
#endif

#include <string>

#include "OSHeaders.h"


class OS
{
    public:
    
        //call this before calling anything else
        static void Initialize();

        static Int32 Min(Int32 a, Int32 b)   { if (a < b) return a; return b; }
		static Int32 Max(Int32 a, Int32 b)   { if (a > b) return a; return b; }
        
        //
        // Milliseconds always returns milliseconds since Jan 1, 1970 GMT.
        // This basically makes it the same as a POSIX time_t value, except
        // in msec, not seconds. To convert to a time_t, divide by 1000.
        static Int64   Milliseconds();

        static Int64   Microseconds();
        
		static OS_Error GetErrno(); 


        //because the OS doesn't seem to have these functions
        static Int64   HostToNetworkInt64(Int64 hostOrdered);
        static Int64   NetworkToHostInt64(Int64 networkOrdered);
                            
		static Int64	TimeMilli_To_Fixed64Secs(Int64 inMilliseconds)
                        { return (Int64) ( (Float64) inMilliseconds / 1000) * ((Int64) 1 << 32 ) ; }
		
		static Int64	TimeMilli_To_1900Fixed64Secs(Int64 inMilliseconds)
						{ return TimeMilli_To_Fixed64Secs(sMsecSince1900) + TimeMilli_To_Fixed64Secs(inMilliseconds); }

		static Int64	TimeMilli_To_UnixTimeMilli(Int64 inMilliseconds)
						{ return inMilliseconds; }

		static time_t	TimeMilli_To_UnixTimeSecs(Int64 inMilliseconds)
						{ return (time_t)  ( (Int64) TimeMilli_To_UnixTimeMilli(inMilliseconds) / (Int64) 1000); }
		
		static time_t 	UnixTime_Secs(void) // Seconds since 1970
						{ return TimeMilli_To_UnixTimeSecs(Milliseconds()); }

        static time_t   Time1900Fixed64Secs_To_UnixTimeSecs(Int64 in1900Fixed64Secs)
                        { return (time_t)( (Int64)  ((Int64)  ( in1900Fixed64Secs - TimeMilli_To_Fixed64Secs(sMsecSince1900) ) /  ((Int64) 1 << 32)  ) ); }
                            
        static Int64   Time1900Fixed64Secs_To_TimeMilli(Int64 in1900Fixed64Secs)
                        { return   ( (Int64) ( (Float64) ((Int64) in1900Fixed64Secs - (Int64) TimeMilli_To_Fixed64Secs(sMsecSince1900) ) / (Float64)  ((Int64) 1 << 32) ) * 1000) ; }
 
        // Returns the offset in hours between local time and GMT (or UTC) time.
        static Int32   GetGMTOffset();
                            
        //Both these functions return QTSS_NoErr, QTSS_FileExists, or POSIX errorcode
        //Makes whatever directories in this path that don't exist yet 
        static OS_Error RecursiveMakeDir(char *inPath);
        //Makes the directory at the end of this path
        static OS_Error MakeDir(char *inPath);
        
		static char * CTime(const time_t *timep, char* buffer, int buffLen);

		static Bool DelFile(const char* pFile);
		static Bool DelDir(const char* pDir);
		static Bool RecursiveDelDir(const char *inPath);
        // Discovery of how many processors are on this machine
        static UInt32   GetNumProcessors();
        
        // CPU Load
        static Float32  GetCurrentCPULoadPercent();
        
	static Bool ConvertTimeToString(time_t v_t,char* v_str);        

        static Int64   InitialMSec()       { return sInitialMsec; }
        static Float32  StartTimeMilli_Float() { return (Float32) ( (Float64) ( (Int64) OS::Milliseconds() - (Int64) OS::InitialMSec()) / (Float64) 1000.0 ); }
        static Int64   StartTimeMilli_Int()      { return (OS::Milliseconds() - OS::InitialMSec()); }

		static void Sleep(UInt32 inMsec);

		static Bool IsFileExist(const char* fileName);
		static UInt64 LocalTimeToTime(const std::string& strLocalTime);

		static Int32	Rand();
			
   private:
	   static UInt64 DateToSecond(Int32 nYear, Int32 nMounth, Int32 nDay, Int32 nHour, Int32 nMin, Int32 nSec);	   
    
        static double sDivisor;
        static double sMicroDivisor;
        static Int64 sMsecSince1900;
        static Int64 sMsecSince1970;
        static Int64 sInitialMsec;
        static Int32 sMemoryErr;
        static void SetDivisor();
        static Int64 sWrapTime;
        static Int64 sCompareWrap;
        static Int64 sLastTimeMilli;
};


#endif
